package xyz.tanxiao.links.common.utils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 实体类参数校验处理器
 *
 * @author 万成波
 * @email 2300064869@qq.com
 * @createTime 2022-07-28 14:51:58 星期四
 */
public class ValidationUtils {

	/**
	 * 校验器
	 */
	private static Validator validator;


	public enum ThrowTypeEnum {
		FIRST, ALL
	}


	/**
	 * 获取并初始化参数校验器
	 *
	 * @return 校验器
	 */
	private static Validator getDefaultValidator() {
		if (Objects.isNull(validator)) {
			validator = Validation.buildDefaultValidatorFactory().getValidator();
		}
		return validator;
	}


	/**
	 * 抛出错误参数信息
	 *
	 * @param throwType 消息抛出方式
	 * @param illegalParams 错误参数
	 */
	private static void throwMessage(ThrowTypeEnum throwType, List<ConstraintViolation<Object>> illegalParams) {
		if (illegalParams.isEmpty()) {
			return;
		}
		if (throwType == ThrowTypeEnum.ALL) {
			// 抛出所有参数校验结果
			StringBuilder errorMessage = new StringBuilder();
			illegalParams.forEach(illegalParam -> errorMessage.append(illegalParam.getMessage()).append(";"));
			throw new RuntimeException(errorMessage.toString());
		} else {
			// 抛出首个参数校验结果
			ConstraintViolation<Object> illegalParam = illegalParams.get(0);
			throw new RuntimeException(illegalParam.getMessage());
		}
	}


	/**
	 * 校验实体类参数
	 *
	 * @param entity 实体类
	 * @param throwType 消息抛出方式
	 * @param groups 分组校验
	 */
	public static void validate(Object entity, ThrowTypeEnum throwType, Class<?> ...groups) {
		// 非法参数校验结果
		Set<ConstraintViolation<Object>> illegalParams;
		// 校验类型
		if (Objects.isNull(groups)) {
			// 普通校验
			illegalParams = getDefaultValidator().validate(entity);
		} else {
			// 分组校验
			illegalParams = getDefaultValidator().validate(entity, groups);
		}
		// 抛出错误参数信息
		throwMessage(throwType, new ArrayList<>(illegalParams));
	}

}
